package cn.huiyunche.base.service.interfaces.impl;

import cn.huiyunche.base.service.enums.AccPaytypeEnum;
import cn.huiyunche.base.service.enums.UserLevelEnum;
import cn.huiyunche.base.service.enums.UserTypeEnum;
import cn.huiyunche.base.service.interfaces.*;
import cn.huiyunche.base.service.mappers.BScoresTurnoverMapper;
import cn.huiyunche.base.service.mappers.ext.BScoresTurnoverViewMapper;
import cn.huiyunche.base.service.model.*;
import cn.huiyunche.base.service.vo.BScoresTurnoverVo;
import cn.huiyunche.base.service.vo.PageVo;
import cn.huiyunche.base.service.vo.UserShowVo;
import cn.huiyunche.tools.basic.exceptions.BusinessException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.jsonwebtoken.lang.Collections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 积分流水接口实现类
 *
 * @author lm
 */
@Service
public class BScoresTurnoverServiceImpl implements BScoresTurnoverService {

    private static final Logger LOGGER = LoggerFactory.getLogger(BScoresTurnoverServiceImpl.class);

    @Autowired
    private BScoresTurnoverMapper bScoresTurnoverMapper = null;

    @Autowired
    private BScoresTurnoverViewMapper bScoresTurnoverViewMapper = null;

    @Autowired
    private UserService userService = null;

    @Autowired
    private BScoresDiscountService bScoresDiscountService = null;

    @Autowired
    private BScoresService bScoresService = null;

    @Autowired
    private BScoresLevelService bScoresLevelService = null;

    private BScoresTurnoverMapper getBScoresTurnoverMapper() {
        return this.bScoresTurnoverMapper;
    }

    private BScoresTurnoverViewMapper getBScoresTurnoverViewMapper() {
        return this.bScoresTurnoverViewMapper;
    }

    private UserService getUserService() {
        return this.userService;
    }

    private BScoresDiscountService getBScoresDiscountService() {
        return this.bScoresDiscountService;
    }

    private BScoresService getBScoresService() {
        return this.bScoresService;
    }

    private BScoresLevelService getBScoresLevelService() {
        return this.bScoresLevelService;
    }

    // 查询当前登录用户
    public UserShowVo getUserShowVo() {
        try {
            return this.getUserService().getCurrentUser();
        } catch (Exception e) {
            LOGGER.error("select current user ERROR : {}.", e);
            throw new BusinessException("查询当前登录用户异常");
        }
    }

    @Autowired
    private CompanyService companyService = null;

    private CompanyService getCompanyService() {
        return this.companyService;
    }

    /**
     * 用户注册添加积分
     *
     * @param userType
     */
    @Override
    public void addDiscountScores(Long userId, int userType) {
        LOGGER.info("add user scores turnover params userId : {}, userType : {}.", userId, userType);
        try {
            // 根据用户ID 查询用户名称
            SUser user = this.getUserService().selectByPrimaryKey(userId);
            if (userType == UserTypeEnum.COMPANY.getValue() || userType == UserTypeEnum.SCOMPANY.getValue()) {
                userId = this.getBCompanyUserService().getCompanyIdByUserId(userId);
                Map<String, Object> map = this.getCompanyService().selectById(userId);
                BCompany company = (BCompany) map.get("companyData");
                user.setRealName(company.getCompanyName());
            }
            LOGGER.info("add user scores turnover params userId : {}, user : {}.", userId, JSONObject.toJSONString(user));

            List<BScoresDiscount> BScoresDiscounts = this.getBScoresDiscountService().selectByUserType(userType, AccPaytypeEnum.REGISTER.getValue());
            LOGGER.info("add user scores turnover params userId : {}, BScoresDiscounts : {}.", userId, JSONObject.toJSONString(BScoresDiscounts));
            if (!Collections.isEmpty(BScoresDiscounts)) {
                for (BScoresDiscount bScoresDiscount : BScoresDiscounts) {
                    LOGGER.info("add user scores turnover params userId : {}, BScoresDiscountId : {}.", userId, JSONObject.toJSONString(bScoresDiscount.getId()));
                    BScoresTurnover turnover = new BScoresTurnover();
                    turnover.setBusinessId(bScoresDiscount.getId());    // 活动ID
                    turnover.setBusinessType(bScoresDiscount.getType());    // 活动描述/类型
                    turnover.setScore(bScoresDiscount.getScores()); // 积分
                    turnover.setUserId(userId);
                    if (user != null) {
                        turnover.setUserName(user.getRealName());
                    } else {
                        turnover.setUserName("托运个人注册");
                    }
                    turnover.setUserType(userType);
                    turnover.setIsused(true);

                    turnover.setCreateTime(new Date());
                    turnover.setUpdateTime(new Date());

                    this.getBScoresTurnoverMapper().insertSelective(turnover);
                    LOGGER.info("add user scores turnover params userId : {} FINISH.", userId);

                    //添加积分 余额表
                    this.addUserDiscountScoresForSign(turnover);
                }
            }
        } catch (Exception e) {
            LOGGER.error("add user scores turnover params userId : {}, userType : {}, error : {}.", userId, userType, e);
            throw new BusinessException("用户注册添加用户积分流水异常");
        }
    }

    /**
     * 添加积分 余额表
     * -- 用户注册 添加积分
     * -- 司机提现 扣除积分(抵扣手续费)
     *
     * @param turnover
     */
    private void addUserDiscountScoresForSign(BScoresTurnover turnover) {
        BScores bScores = new BScores();
        LOGGER.info("add user scores turnover addUserDiscountScores params addUserDiscountScores : {}.", turnover);
        try {
            bScores.setUserId(turnover.getUserId());
            bScores.setUserName(turnover.getUserName());
            bScores.setUserType(turnover.getUserType());
            bScores.setScores(turnover.getScore());
            if (turnover.getScore().compareTo(BigDecimal.ZERO) == 1) {
                bScores.setScoresTotal(turnover.getScore());
            }
            bScores.setCreateTime(new Date());
            bScores.setUpdateTime(new Date());

            LOGGER.info("add user scores turnover addUserDiscountScores select level params userType : {}.", turnover.getUserType());
            BScoresLevel level = this.getBScoresLevelService().selectByLevel(turnover.getUserType(), UserLevelEnum.LEVEL_A.getValue());
            LOGGER.info("add user scores turnover select level params userType : {}, level : {}.", turnover.getUserType(), UserLevelEnum.LEVEL_A.getValue());
            if (level == null) {
                LOGGER.info("add user scores turnover select level : {}.", level);
                throw new BusinessException("未查询到该类型用户等级");
            }
            bScores.setLevelId(level.getId());
            bScores.setLevel(level.getLevel());
            bScores.setLevelName(level.getLevelName());

            this.getBScoresService().addScores(bScores);
        } catch (Exception e) {
            LOGGER.error("add user scores turnover addUserDiscountScores params addUserDiscountScores : {}, ERROR : {}.", JSON.toJSONString(turnover), e);
            throw new BusinessException("用户注册添加用户积分调用添加余额方法异常");
        }
    }

    @Autowired
    private BCompanyUserService bCompanyUserService = null;

    private BCompanyUserService getBCompanyUserService() {
        return this.bCompanyUserService;
    }

    /**
     * 根据用户查询用户明细
     * －－ 查询用户 积分流水
     *
     * @param userShowVo
     * @return
     */
    @Override
    public Map<String, Object> selectTurnoversByUser(UserShowVo userShowVo, PageVo page) {
        LOGGER.info("select user turnovers params userShowVo : {}, {}", userShowVo, page);
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            BScoresTurnoverExample example = new BScoresTurnoverExample();
            if (userShowVo != null && userShowVo.getId() != null && userShowVo.getUserType() != null) {
                example.setLimitStart(page.getStartIndex());
                example.setLimitEnd(page.getPageSize());
                if (example.getOrderByClause() != null) {
                    example.setOrderByClause(page.getOrder());
                } else {
                    example.setOrderByClause(" id DESC");
                }
                Long userId = userShowVo.getId();
                Integer userType = userShowVo.getUserType();
                if (userType == UserTypeEnum.SCOMPANY.getValue() || userType == UserTypeEnum.COMPANY.getValue()) {
                    userId = this.getBCompanyUserService().getCompanyIdByUserId(userId);
                }
                example.createCriteria().andUserIdEqualTo(userId).
                        andUserTypeEqualTo(userType).andIsusedEqualTo(true).andScoreNotEqualTo(BigDecimal.ZERO);
                page.setTotalRecord(this.getBScoresTurnoverViewMapper().countByExample(example));
                List<BScoresTurnoverVo> turnovers = this.getBScoresTurnoverViewMapper().selectByExample(example);

                map.put("page", page);
                map.put("turnovers", turnovers);

                return map;
            } else {
                LOGGER.info("select user turnovers params userShowVo : {}.", JSON.toJSONString(userShowVo));
                throw new BusinessException("查询用户积分流水未查询到当前登录用户");
            }
        } catch (Exception e) {
            LOGGER.error("select user turnovers params userShowVo : {}, ERROR : {}.", JSON.toJSONString(userShowVo), e);
            throw new BusinessException("查询用户积分流水异常");
        }
    }

    /**
     * 根据当前登录用户
     * 查询积分流水 scoresTurnover
     * －－ 托运企业
     *
     * @return
     */
    @Override
    public Map<String, Object> selectTurnoversByCurrent(PageVo page) {
        LOGGER.info("selectTurnoversByCurrent params : {}", page);
        try {
            // 查询当前用户
            UserShowVo userShowVo = this.getUserShowVo();
            LOGGER.info("select current user userShowVo : {}.", JSON.toJSONString(userShowVo));
            if (null == userShowVo) {
                LOGGER.info("select current user is not exist userShowVo : {}.", JSON.toJSONString(userShowVo));
                throw new BusinessException("当前登录账户不存在");
            }

            return this.selectTurnoversByUser(userShowVo, page);
        } catch (Exception e) {
            LOGGER.error("select user turnovers params ERROR : {}.", e);
            throw new BusinessException("查询用户积分流水异常");
        }
    }

    /**
     * 添加积分
     * -- 用户下单 扣除积分
     * -- 用户提现 扣除积分
     *
     * @param bScoresTurnover
     * @param flag            true: 添加到余额 false: 不添加到余额
     * @return
     */
    @Override
    public int insert(BScoresTurnover bScoresTurnover, boolean flag) {
        LOGGER.info("insert into bScoresTurnover : {}, {}", bScoresTurnover, flag);
        int count = 0;
        try {
            if (bScoresTurnover.getId() != null) {
                count = this.getBScoresTurnoverMapper().updateByPrimaryKeySelective(bScoresTurnover);
            } else {
                count = this.getBScoresTurnoverMapper().insertSelective(bScoresTurnover);
            }

            if (flag) {
                //添加积分 余额表
                this.addUserDiscountScores(bScoresTurnover);
            }
        } catch (Exception e) {
            LOGGER.info("insert into bScoresTurnover : {}, error : {}.", JSON.toJSONString(bScoresTurnover), e);
            throw new BusinessException("添加积分数据异常");
        }
        return count;
    }

    /**
     * 用户下单 使用积分－扣除
     * 快速提现 使用积分－扣除
     *
     * @param turnover
     */
    private void addUserDiscountScores(BScoresTurnover turnover) {
        LOGGER.info("addUserDiscountScores params : {}", turnover);
        BScores bScores = new BScores();
        LOGGER.info("user create order user scores. add user scores turnover addUserDiscountScores params addUserDiscountScores : {}.", JSON.toJSONString(turnover));
        try {
            bScores.setUserId(turnover.getUserId());
            bScores.setUserName(turnover.getUserName());
            bScores.setUserType(turnover.getUserType());
            bScores.setScores(turnover.getScore());

            bScores.setUpdateTime(new Date());
            LOGGER.info("user create order user scores. add user scores turnover addUserDiscountScores params addUserDiscountScores : {}, bScores : {}.", JSON.toJSONString(turnover), JSON.toJSONString(bScores));
            this.getBScoresService().addScores(bScores);
        } catch (Exception e) {
            LOGGER.error("user create order user scores. add user scores turnover addUserDiscountScores params addUserDiscountScores : {}, ERROR : {}.", JSON.toJSONString(turnover), e);
            throw new BusinessException("用户注册添加用户积分调用添加余额方法异常");
        }
    }

    /**
     * @param paymentId 支付记录ID
     * @param orderId   客户订单ID
     *                  根据客户订单ID
     *                  查询用户未使用的积分抵扣金额
     * @param orderId
     */
    @Override
    public BigDecimal getNotUsedScores(Long paymentId, Long orderId) {
        LOGGER.info("select unused scoers params orderId : {}, {}", paymentId, orderId);
        try {
            BScoresTurnoverExample example = new BScoresTurnoverExample();
            example.setOrderByClause(" id DESC");
            example.createCriteria().andBusinessIdEqualTo(orderId).andBusinessTypeEqualTo(AccPaytypeEnum.ORDER.getValue()).andIsusedEqualTo(false);
            List<BScoresTurnover> bsScoresTurnovers = this.getBScoresTurnoverMapper().selectByExample(example);
            if (Collections.isEmpty(bsScoresTurnovers)) {
                LOGGER.info("select unused scoers params orderId : {} is not record.", orderId);
                return null;
            }
            BScoresTurnover bScoresTurnover = bsScoresTurnovers.get(0);
            Long userId = bScoresTurnover.getUserId();
            Integer userType = bScoresTurnover.getUserType();
            BScores bScores = this.getBScoresService().selectByUserIdAndUserType(userId, userType);
            if (bScores != null) {
                BigDecimal scores = bScores.getScores();
                if (scores.compareTo(BigDecimal.ZERO) == 1) {
                    // bScoresTurnover.setScore(bScoresTurnover.getScore().abs().negate());
                    // bScoresTurnover.setIsused(true);
                    // 将记录更新成 已使用(XX)
                    // 将支付记录ID 放到积分记录中，等支付回调扣除积分使用
                    bScoresTurnover.setPaymentId(paymentId);
                    this.getBScoresTurnoverMapper().updateByPrimaryKey(bScoresTurnover);

                    // this.insert(bScoresTurnover, true);
                    return bScoresTurnover.getCost();
                }
            }
        } catch (Exception e) {
            LOGGER.info("select unused scoers params orderId : {}, error : {}.", orderId, e);
            throw new BusinessException("查询用户未使用的积分抵扣金额异常");
        }
        return null;
    }

    /**
     * 根据paymentId 扣除积分
     *
     * @param paymentId
     * @return
     */
    @Override
    public int updateByPaymentId(Long paymentId) {
        LOGGER.info("updateByPaymentId param : {}", paymentId);
        try {
            LOGGER.info("sub scores by paymentId params id : {}.", paymentId);
            BScoresTurnoverExample example = new BScoresTurnoverExample();
            example.createCriteria().andPaymentIdEqualTo(paymentId);
            List<BScoresTurnover> turnovers = this.getBScoresTurnoverMapper().selectByExample(example);
            if (!Collections.isEmpty(turnovers)) {
                BScoresTurnover bScoresTurnover = turnovers.get(0);
                bScoresTurnover.setScore(bScoresTurnover.getScore().abs().negate());
                bScoresTurnover.setIsused(true);
                return this.insert(bScoresTurnover, true);
            }
        } catch (Exception e) {
            LOGGER.error("sub scores by paymentId params id : {}, error : {}.", paymentId, e);
            throw new BusinessException("支付成功扣除积分异常");
        }
        return 0;
    }

}